﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Antlr.StringTemplate;
namespace gxc2csharp.Translator
{
   
   public class GxcParser
   {

   	  public Dictionary<string, string> Symbols{get;set;}
      List<string> execMethod;
      TextWriter writer;
      GXCFunctionCallParser gXCFunctionCallParser; 
      public string namespaceName="Geosoft.GXNet.Generated";
      public string className = "Foo";
	  StringTemplateGroup templates;
      public GxcParser()
      {
         Symbols = new Dictionary<string, string>();
         execMethod = new List<string>();
         templates = new StringTemplateGroup("gxc",@".\CodeTemplates");

      }
      public void ParseSymbolFile(string symbolFile)
      {
         if(File.Exists(symbolFile))
         {
            using (StreamReader reader = new StreamReader(symbolFile))
            {
               while(!reader.EndOfStream)
               {
                  string line = reader.ReadLine().Trim();
                  if (line.StartsWith("//"))
                     continue;
                  int index = line.IndexOf(';');
                  if (index != -1)
                     line = line.Substring(0, index);
                  string [] tokens = line.Split(' ', ',', ';');
                  string type = "";
                  
                  foreach (string token in tokens)
                  {
                     if (string.IsNullOrEmpty(token) == false)
                     {
                        if (type == "")
                        {
                           type = token.Trim();
                           
                           if(type.StartsWith("string"))
                              type ="string";
                           if (type != "real" && type != "int" && type != "string")
                              type = "C" + type;
                           
                        }
                        else
                        {

                           Symbols.Add(token, type);
                        }
                     }
                  }


               }
               reader.Close();
            }

         }

      }

      public void ReadExecuteMethodFile(string exeMethodFile)
      {
         if (File.Exists(exeMethodFile))
         {
            using (StreamReader reader = new StreamReader(exeMethodFile))
            {
               while (!reader.EndOfStream)
               {
                  execMethod.Add(reader.ReadLine());

               }
               reader.Close();
            }

         }
      }

      public void WriteCSCode(string csFileName)
      {
         
         StringTemplate st = templates.GetInstanceOf("partial_code");
             
         
         gXCFunctionCallParser = new GXCFunctionCallParser(Symbols);
         
         
         using (writer = new StreamWriter(csFileName))
            {
               AutoIndentWriter templateWriter = new AutoIndentWriter(writer);

               st.Write(templateWriter);
               string tab = new string(' ', 9);
              
               foreach (var kvp in Symbols)
               {
                 
                  if(kvp.Value[0]=='C')
                      writer.WriteLine(tab+"{0} {1}=null;", kvp.Value, kvp.Key);
                  else if(kvp.Value=="string")
                     writer.WriteLine(tab + "{0} {1}=\"\";", kvp.Value, kvp.Key);
                  else
                     writer.WriteLine(tab + "{0} {1};", kvp.Value, kvp.Key);
                 
               }
               writer.WriteLine(tab + "try");
               writer.WriteLine(tab + "\t{\n");
               foreach (string line in execMethod)
               {
                  string trimline = line.Trim();
                  if (trimline.StartsWith("//") || trimline == "")
                  {
                     writer.WriteLine(tab + line);
                     continue;
                  }
                  if (line.Contains("="))
                  {
                     int index = line.IndexOf('=');
                     if (char.IsSeparator(line, index - 1) && char.IsSeparator(line, index + 1))
                     {

                        writer.WriteLine(tab + HandleAssignment(line));
                         continue;
                     }
                     
                  }

                  writer.WriteLine(tab + gXCFunctionCallParser.GetCSharpSignatureForFunction(line));
                  

               }
               writer.WriteLine(tab + "}");
               writer.WriteLine(tab + "finally");
               writer.WriteLine(tab + "\t{\n");
               foreach (var kvp in Symbols)
               {
                  if (kvp.Value[0]== 'C')
                  {
                     writer.WriteLine(tab + "if({0} != null)", kvp.Key);
                     writer.WriteLine(tab + "\t{0}.Dispose();", kvp.Key);
                  }
                 
               }

               

              
               writer.WriteLine(tab + "}");
               writer.WriteLine(tab + "}");
               writer.Close();
            }

         
      }

      private string HandleAssignment(string line)
      {
         string temp = gXCFunctionCallParser.GetCSharpSignatureForFunction(line);


         return temp;
      }
   }
}
